package com.liushao.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.liushao.SmsDTO;
import com.liushao.constant.MQConst;
import com.liushao.entity.UserAccount;
import com.liushao.entity.UserInfo;
import com.liushao.entity.bo.TransFlowBO;
import com.liushao.enums.TransTypeEnum;
import com.liushao.hfb.FormHelper;
import com.liushao.hfb.HfbConst;
import com.liushao.hfb.RequestHelper;
import com.liushao.mapper.UserAccountMapper;
import com.liushao.mapper.UserInfoMapper;
import com.liushao.service.*;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.liushao.util.LendNoUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

/**
 * <p>
 * 用户账户 服务实现类
 * </p>
 *
 * @author chen
 * @since 2025-01-03
 */
@Service
public class UserAccountServiceImpl extends ServiceImpl<UserAccountMapper, UserAccount> implements UserAccountService {

    @Autowired
    private MQService mqService;

    @Autowired
    private UserInfoMapper userInfoMapper;

    @Autowired
    private TransFlowService transFlowService;

    @Autowired
    private UserBindService userBindService;

    @Autowired
    private UserInfoService userInfoService;


    @Override
    public String commitCharge(BigDecimal chargeAmt, Long userId) {
        UserInfo userInfo = userInfoMapper.selectById(userId);

        String bindCode = userInfo.getBindCode();

        //判断一下 用户绑定的状态  你们做

        //准备参数
        /*
        agent_id	int		是	给商户分配的唯一标识
        agent_bill_no	string	50	是	商户充值单号（要求唯一）
        bind_code	string	50	是	充值人绑定协议号。
        charge_amt	decimal		是	充值金额，即充值到汇付宝的金额。支持小数点后2位。
        fee_amt	decimal		是	商户收取用户的手续费。支持小数点后2位。可以传0。
        注意：从银行卡扣除金额= charge_amt+ fee_amt，用户汇付宝余额增加charge_amt，fee_amt转到商户账户。
        notify_url	string	255	是	通知商户充值成功的完整地址
        return_url	string	255	否	充值完成后同步返回商户的完整地址。
        timestamp	long		是	时间戳。从1970-01-01 00:00:00算起的毫秒数。
        sign	string	32	是	验签参数。

         */



        Map<String,Object> paramMap = new HashMap<>();
        paramMap.put("agentId", HfbConst.AGENT_ID);//给商户分配的唯一标识
        paramMap.put("agentBillNo", LendNoUtils.getNo());//商户充值单号（要求唯一）
        paramMap.put("bindCode",bindCode);//充值人绑定协议号。
        paramMap.put("chargeAmt",chargeAmt);//充值金额

        paramMap.put("feeAmt",new BigDecimal("0"));//	商户收取用户的手续费
        paramMap.put("notifyUrl",HfbConst.RECHARGE_NOTIFY_URL);//通知商户充值成功的完整地址
        paramMap.put("returnUrl",HfbConst.RECHARGE_RETURN_URL); //充值完成后同步返回商户的完整地址。
        paramMap.put("timestamp", new Date().getTime());//时间戳
        paramMap.put("sign", RequestHelper.getSign(paramMap));//验签参数


        String form = FormHelper.buildForm(HfbConst.RECHARGE_URL, paramMap);//第一个参数是 用户绑定的url   ，第二个 接口需要的参数 !!


        return form;
    }

    @Override
    public void notifyss(Map<String, Object> objectMap) {

        /*
          bind_code	string	50	是	充值人绑定协议号。
charge_amt	decimal		是	充值金额

         */
        System.out.println("充值成功了!!!");
         String bindCode= (String) objectMap.get("bindCode");
        String chargeAmt= (String) objectMap.get("chargeAmt");

        baseMapper.updateUserAccount(bindCode,new BigDecimal(chargeAmt),new BigDecimal(0));

        //增加交易流水

        // 发个短信给你
        String mobile = userInfoService.getMobileByBindCode(bindCode);
        //构建message
        SmsDTO smsDTO = new SmsDTO();
        smsDTO.setMobile(mobile);
        smsDTO.setMessage("充值成功了！");
        mqService.sendMessage(
                MQConst.EXCHANGE_TOPIC_SMS,
                MQConst.ROUTING_TOPIC_SMS,
                smsDTO);


        //agent_bill_no	string	50	是	商户充值订单号
        String agentBillNo = (String) objectMap.get("agentBillNo");
        boolean result = transFlowService.isSaveTransFlow(agentBillNo);

        if(result){
            System.out.println("幂等性返回了.....");
            return;
        }

        //TODO   增加交易流水




    }

    @Override
    public BigDecimal getAccountById(Long userId) {
        QueryWrapper<UserAccount> wrapper = new QueryWrapper<>();
        wrapper.eq("user_id",userId);

        UserAccount userAccount = baseMapper.selectOne(wrapper);
          //账户的钱
        BigDecimal amount = userAccount.getAmount();


        return amount;
    }

    @Override
    public String commitWithdraw(BigDecimal fetchAmt, Long userId) {
          //提现
        //账户可用余额要充足   当前用户的余额 >= 当前用户的提现金额
        BigDecimal amount = this.getAccountById(userId);
        //判断  ？？　
        String bindCode = userBindService.getBindCodeByUserId(userId);
        /*






notify_url	string	500	是	通知商户提现的完整url。
用户提现申请成功、提现处理结果都通知给该地址。
timestamp	long		是	时间戳。从1970-01-01 00:00:00算起的毫秒数。
sign	string	32	是	验签参数。

         */

        Map<String,Object> map = new HashMap<>();
        map.put("agentId",HfbConst.AGENT_ID);//agent_id	int		是	给商户分配的唯一标识
        map.put("agentBillNo",LendNoUtils.getWithdrawNo());//	string	50	是	商户提现单号。只能由数字、字母组成，12~50个字符。
        map.put("bindCode",bindCode);//	string	50	是	用户绑定协议号。只能由数字、字母组成，12~50个字符。
        map.put("fetchAmt",fetchAmt);//	decimal		是	提现金额。必须大于0。最多支持小数点后两位。
        map.put("feeAmt",new BigDecimal(0));//	decimal		是	商户收取用户的手续费。不能小于0。最多支持小数点后两位。
        map.put("returnUrl",HfbConst.WITHDRAW_RETURN_URL);//	string	100	是	用户提现申请成功后，同步返回到商户的完整url。
        map.put("notifyUrl",HfbConst.WITHDRAW_NOTIFY_URL);//notify_url	string	500	是	通知商户提现的完整url。
        map.put("timestamp",RequestHelper.getTimestamp());//timestamp	long		是	时间戳。从1970-01-01 00:00:00算起的毫秒数。
        String sign = RequestHelper.getSign(map);
        map.put("sign",sign);//sign	string	32	是	验签参数。

        // 构建自动的表单
          String formStr= FormHelper.buildForm(HfbConst.WITHDRAW_URL,map);


        return formStr;
    }
@Transactional(rollbackFor = Exception.class)
    @Override
    public void notifysssss(Map<String, Object> objectMap) {
        //提现成功了
        System.out.println("提现成功了.......");
         // 商户提现单号
        String agentBillNo = (String) objectMap.get("agentBillNo");
        boolean result = transFlowService.isSaveTransFlow(agentBillNo);
        if(result){
             //存在
            System.out.println("幂等性返回.....");
            return;
        }
        /*
         bind_code	string	50	是	充值人绑定协议号。
fetch_amt	decimal		是	提现金额（与商户传过来的一致）

         */

        String bindCode = (String) objectMap.get("bindCode");
        String fetchAmt = (String) objectMap.get("fetchAmt");

        baseMapper.updateUserAccount(bindCode,new BigDecimal("-"+fetchAmt),new BigDecimal(0));

        //增加交易流水
    /*
        private String agentBillNo;//商户充值订单号
    private BigDecimal amount;//账户的可用余额
    private String bindCode;//绑定
    private TransTypeEnum transTypeEnum;//绑定协议号
    private String memo;//备忘
     */
    TransFlowBO transFlowBO = new TransFlowBO(
            agentBillNo,
            new BigDecimal(fetchAmt),
            bindCode,
            TransTypeEnum.WITHDRAW,
            "提现"
    );

    transFlowService.saveTransFlow(transFlowBO);



    }
}
